Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
CRAP | |
95.92% |
47 / 49 |
| GrantedCategoryFieldSetter | |
0.00% |
0 / 1 |
|
33.33% |
1 / 3 |
20 | |
95.92% |
47 / 49 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
| setFieldData | |
0.00% |
0 / 1 |
15 | |
96.55% |
28 / 29 |
|||
| areAllCategoriesVisibleOnEntity | |
0.00% |
0 / 1 |
4.01 | |
92.31% |
12 / 13 |
|||
| <?php | |
| /* | |
| * This file is part of the Akeneo PIM Enterprise Edition. | |
| * | |
| * (c) 2017 Akeneo SAS (http://www.akeneo.com) | |
| * | |
| * For the full copyright and license information, please view the LICENSE | |
| * file that was distributed with this source code. | |
| */ | |
| namespace Akeneo\Pim\Permission\Component\Updater\Setter; | |
| use Akeneo\Pim\Enrichment\Component\Product\Model\ProductInterface; | |
| use Akeneo\Pim\Enrichment\Component\Product\Model\ProductModelInterface; | |
| use Akeneo\Pim\Enrichment\Component\Product\Updater\Setter\AbstractFieldSetter; | |
| use Akeneo\Pim\Enrichment\Component\Product\Updater\Setter\FieldSetterInterface; | |
| use Akeneo\Pim\Permission\Component\Attributes; | |
| use Akeneo\Tool\Component\Classification\CategoryAwareInterface; | |
| use Akeneo\Tool\Component\StorageUtils\Exception\InvalidPropertyException; | |
| use Doctrine\Common\Persistence\ObjectManager; | |
| use Doctrine\Common\Persistence\ObjectRepository; | |
| use Doctrine\Common\Util\ClassUtils; | |
| use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | |
| use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; | |
| use Symfony\Component\Security\Core\Exception\InvalidArgumentException; | |
| /** | |
| * Check if category is at least "viewable" to be associated to a resource | |
| * | |
| * @author Marie Bochu <marie.bochu@akeneo.com> | |
| */ | |
| class GrantedCategoryFieldSetter extends AbstractFieldSetter implements FieldSetterInterface | |
| { | |
| /** @var FieldSetterInterface */ | |
| private $categoryFieldSetter; | |
| /** @var AuthorizationCheckerInterface */ | |
| private $authorizationChecker; | |
| /** @var ObjectRepository */ | |
| private $categoryAccessRepository; | |
| /** @var TokenStorageInterface */ | |
| private $tokenStorage; | |
| /** @var ObjectManager */ | |
| private $entityManager; | |
| /** | |
| * @param FieldSetterInterface $categoryFieldSetter | |
| * @param AuthorizationCheckerInterface $authorizationChecker | |
| * @param ObjectRepository $categoryAccessRepository | |
| * @param TokenStorageInterface $tokenStorage | |
| * @param ObjectManager $entityManager | |
| * @param array $supportedFields | |
| */ | |
| public function __construct( | |
| FieldSetterInterface $categoryFieldSetter, | |
| AuthorizationCheckerInterface $authorizationChecker, | |
| ObjectRepository $categoryAccessRepository, | |
| TokenStorageInterface $tokenStorage, | |
| ObjectManager $entityManager, | |
| array $supportedFields | |
| ) { | |
| $this->categoryFieldSetter = $categoryFieldSetter; | |
| $this->authorizationChecker = $authorizationChecker; | |
| $this->categoryAccessRepository = $categoryAccessRepository; | |
| $this->tokenStorage = $tokenStorage; | |
| $this->entityManager = $entityManager; | |
| $this->supportedFields = $supportedFields; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function setFieldData($entityWithCategories, $field, $data, array $options = []) | |
| { | |
| $areCategoriesVisible = $this->areAllCategoriesVisibleOnEntity($entityWithCategories); | |
| $wasOwner = $this->authorizationChecker->isGranted([Attributes::OWN], $entityWithCategories); | |
| if ($entityWithCategories instanceof ProductModelInterface && | |
| $this->authorizationChecker->isGranted(Attributes::EDIT, $entityWithCategories) | |
| ) { | |
| $wasOwner = true; | |
| } | |
| $this->categoryFieldSetter->setFieldData($entityWithCategories, $field, $data, $options); | |
| $isOwner = false; | |
| // TODO: refactor it by introducing a method getCategoriesForVariation for ProductModelInterface | |
| // TODO: and a common interface with ProductInterface | |
| $categories = $entityWithCategories instanceof ProductInterface ? | |
| $entityWithCategories->getCategoriesForVariation() : $entityWithCategories->getCategories(); | |
| foreach ($categories as $category) { | |
| if (!$this->authorizationChecker->isGranted([Attributes::VIEW_ITEMS], $category)) { | |
| throw InvalidPropertyException::validEntityCodeExpected( | |
| $field, | |
| 'category code', | |
| 'The category does not exist', | |
| static::class, | |
| $category->getCode() | |
| ); | |
| } | |
| } | |
| foreach ($entityWithCategories->getCategories() as $category) { | |
| if ($entityWithCategories instanceof ProductModelInterface && | |
| $this->authorizationChecker->isGranted(Attributes::EDIT_ITEMS, $category) | |
| ) { | |
| $isOwner = true; | |
| } elseif ($this->authorizationChecker->isGranted([Attributes::OWN_PRODUCTS], $category)) { | |
| $isOwner = true; | |
| } | |
| } | |
| if (count($entityWithCategories->getCategories()) === 0 && $areCategoriesVisible) { | |
| $isOwner = true; | |
| } | |
| if ($wasOwner && !$isOwner && null !== $entityWithCategories->getId()) { | |
| throw new InvalidArgumentException( | |
| 'You should at least keep your product in one category on which you have an own permission.' | |
| ); | |
| } | |
| } | |
| /** | |
| * In the case the user removes all categories from an resource he owns, he will not loose the ownership of this resource | |
| * (because an uncategorized resource is automatically owned) except if there is still a category the user can not | |
| * view attached to the resource. | |
| * This method check if there are categories he can not view on the resource. | |
| * | |
| * @param CategoryAwareInterface $entityWithCategories | |
| * | |
| * @return bool | |
| */ | |
| protected function areAllCategoriesVisibleOnEntity(CategoryAwareInterface $entityWithCategories) | |
| { | |
| if (null === $entityWithCategories->getId()) { | |
| return true; | |
| } | |
| $entityWithoutPermission = $this->entityManager->getRepository(ClassUtils::getClass($entityWithCategories)) | |
| ->find($entityWithCategories->getId()); | |
| if (null === $entityWithoutPermission) { | |
| return true; | |
| } | |
| $categoryCodes = $entityWithoutPermission->getCategoryCodes(); | |
| if (count($categoryCodes) === 0) { | |
| return true; | |
| } | |
| $user = $this->tokenStorage->getToken()->getUser(); | |
| return $this->categoryAccessRepository->areAllCategoryCodesGranted( | |
| $user, | |
| Attributes::VIEW_ITEMS, | |
| $categoryCodes | |
| ); | |
| } | |
| } |